using System;
using System.Collections.Generic;
using UnityEngine;

namespace EntityKit.Runtime
{
    /// <summary>
    /// 数学工具类
    /// </summary>
    public static class MathHelper
    {
        /// <summary>
        /// 角度转弧度
        /// </summary>
        public static float Deg2Rad(float degrees)
        {
            return degrees * Mathf.Deg2Rad;
        }

        /// <summary>
        /// 弧度转角度
        /// </summary>
        public static float Rad2Deg(float radians)
        {
            return radians * Mathf.Rad2Deg;
        }


        /// <summary>
        /// 向量夹角（角度）
        /// </summary>
        public static float Angle(Vector3 from, Vector3 to)
        {
            return Vector3.Angle(from, to);
        }

        /// <summary>
        /// 向量夹角（弧度）
        /// </summary>
        public static float AngleRad(Vector3 from, Vector3 to)
        {
            return Angle(from, to) * Mathf.Deg2Rad;
        }

        /// <summary>
        /// 向量投影
        /// </summary>
        public static Vector3 Project(Vector3 vector, Vector3 onNormal)
        {
            return Vector3.Project(vector, onNormal);
        }
        
        /// <summary>
        /// 点到线段的最短距离
        /// </summary>
        public static float DistancePointToLineSegment(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
        {
            Vector3 line = lineEnd - lineStart;
            float lineLength = line.magnitude;
            if (lineLength == 0.0f)
                return (point - lineStart).magnitude;

            Vector3 normalizedLine = line / lineLength;
            float t = Vector3.Dot(point - lineStart, normalizedLine);
            t = Mathf.Clamp(t, 0.0f, lineLength);

            Vector3 closestPoint = lineStart + normalizedLine * t;
            return (point - closestPoint).magnitude;
        }

        /// <summary>
        /// 点是否在矩形内
        /// </summary>
        public static bool IsPointInRect(Vector2 point, Rect rect)
        {
            return rect.Contains(point);
        }

        /// <summary>
        /// 点是否在多边形内（2D）
        /// </summary>
        public static bool IsPointInPolygon(Vector2 point, Vector2[] polygon)
        {
            int polygonLength = polygon.Length;
            bool inside = false;
            Vector2 endPoint = polygon[polygonLength - 1];

            foreach (Vector2 startPoint in polygon)
            {
                Vector2 start = startPoint;
                Vector2 end = endPoint;
                endPoint = startPoint;

                if (start.y > end.y)
                {
                    (start, end) = (end, start);
                }

                if (point.y > start.y && point.y <= end.y && point.x <= start.x + (end.x - start.x) * (point.y - start.y) / (end.y - start.y))
                {
                    inside = !inside;
                }
            }

            return inside;
        }
        
        /// <summary>
        /// 检测点是否在Collider范围内
        /// </summary>
        public static bool IsPointInCollider(this Collider collider, Vector3 point)
        {
            return collider.bounds.Contains(point);
        }

        /// <summary>
        /// 将值限制在指定范围内，支持循环
        /// </summary>
        public static float ClampLoop(float value, float min, float max)
        {
            if (value < min)
                return max;
            if (value > max)
                return min;
            return value;
        }
        
        /// <summary>
        /// 将角度限制在0~360范围内
        /// </summary>
        public static float ClampAngle(float angle)
        {
            while (angle < 0)
                angle += 360;
            while (angle > 360)
                angle -= 360;
            return angle;
        }
    }
}